package com.android.server.mock;

import static android.content.pm.PackageManager.MATCH_ALL;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.IActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

public class AmUtil {
    public static final String TAG = "AmUtil";

    // 使用ActivityManagerService获取正在运行的第三方应用，并杀死所有第三方应用
    @SuppressLint("NewApi")
    public static void killBackgroundApps() {
        IActivityManager activityManager = getActivityManager();
        if (activityManager == null) {
            Slog.e(TAG, "killBackgroundApps activityManager = null");
            return;
        }
        try {
            // 获取正在运行的第三方应用
            List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
            if (runningAppProcesses == null || runningAppProcesses.size() == 0) {
                Slog.e(TAG, "killBackgroundApps runningAppProcesses=" + runningAppProcesses);
                return;
            }
            // 杀死所有第三方应用
            for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
                // 10000以下的uid为系统进程
                if (runningAppProcessInfo.uid < Process.FIRST_APPLICATION_UID) {
                    continue;
                }
                String[] pkgList = runningAppProcessInfo.pkgList;
                if (pkgList == null || pkgList.length == 0) {
                    continue;
                }
                for (String pkg : pkgList) {
                    boolean isSystemApp = isSystemApp(pkg, getCurrentUserId());
                    if (isSystemApp) {
                        break;
                    }
                    Slog.d(TAG, "killBackgroundApps " + runningAppProcessInfo.processName + ", uid=" + runningAppProcessInfo.uid);
                    activityManager.killApplicationProcess(runningAppProcessInfo.processName, runningAppProcessInfo.uid);
                }
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public static IActivityManager getActivityManager() {
        return ActivityManager.getService();
    }

    public static boolean isSystemApp(String packageName, int userId) {
        boolean isSystemApp = false;
        try {
            ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, MATCH_ALL, userId);
            if (ai != null) {
                isSystemApp = (ai.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
            }
        } catch (RemoteException e) {
        }
        return isSystemApp;
    }

    @SuppressLint("MissingPermission")
    public static int getCurrentUserId() {
        return ActivityManager.getCurrentUser();
    }

    public static void clearApplicationData(PackageManager packageManager) {
        List<ApplicationInfo> apps = PmUtil.getInstalledApplications(packageManager, 0, getCurrentUserId());
        for (ApplicationInfo applicationInfo : apps) {
            try {
                PackageInfo packageInfo;
                try {
                    packageInfo = packageManager.getPackageInfoAsUser(applicationInfo.packageName, PackageManager.GET_SERVICES, getCurrentUserId());
                } catch (PackageManager.NameNotFoundException e) {
                    Log.w(TAG, "clearApplicationData failed to get PackageInfo for package: " + applicationInfo.packageName + ", userId: " + getCurrentUserId());
                    continue;
                }
                boolean isVPNApp = false;
                if (packageInfo.services != null) {
                    for (ServiceInfo si : packageInfo.services) {
                        if (Manifest.permission.BIND_VPN_SERVICE.equals(si.permission)) {
                            Log.d(TAG, "clearApplicationData package: " + applicationInfo.packageName + " is VPN App");
                            isVPNApp = true;
                            break;
                        }
                    }
                }
                if (!isVPNApp) {
                    getActivityManager().clearApplicationUserData(
                            applicationInfo.packageName, false, null, getCurrentUserId());
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "clearApplicationData " + applicationInfo.packageName + " failed, " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
}
